package com.dwj.auto.comment.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dwj.auto.comment.common.enums.CommentType;
import com.dwj.auto.comment.common.enums.TempLevelEnum;
import com.dwj.auto.comment.common.response.Response;
import com.dwj.auto.comment.dao.entity.CommentTemp;
import com.dwj.auto.comment.dao.mapper.CommentTempMapper;
import com.dwj.auto.comment.handler.ConjunctionHandler;
import com.dwj.auto.comment.model.dto.CommentResultDto;
import com.dwj.auto.comment.model.req.AutoCommentData;
import com.dwj.auto.comment.model.req.AutoCommentReq;
import com.dwj.auto.comment.model.vo.AutoCommentVo;
import com.dwj.auto.comment.service.IAutoCommentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.dwj.auto.comment.common.constant.RedisKey.Comment.*;

/**
 * @ClassName IAutoCommentServiceImpl
 * @Description handler
 * @Author dwjian
 * @Date 2020/2/9 11:39
 */
@Slf4j
@Service
public class AutoCommentServiceImpl implements IAutoCommentService {

    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private CommentTempMapper commentTempMapper;

    @Override
    public Response<List<AutoCommentVo>> autoComment(List<AutoCommentReq> reqList) {
        List<AutoCommentVo> autoCommentVos = new ArrayList<>();
        for (AutoCommentReq req : reqList) {
            //类型 印象 纪律...
            CommentType commentType = CommentType.getEnumByDesc(req.getType());
            for (AutoCommentData commentData : req.getData()) {
                //等级 优秀 良好...
                TempLevelEnum levelEnum = TempLevelEnum.getByDesc(commentData.getName());
                //学生姓名字符串
                String stuNamesStr = commentData.getValue();
                if(StringUtils.isNotEmpty(stuNamesStr)){
                    String[] names = stuNamesStr.split("，");
                    //模板总数量，含权重
                    long size = redisTemplate.opsForList().size(StringUtils.join(DOMAIN, TEMP_WEIGHT_KEY, commentType, ":", levelEnum));
                    if(size > 0){
                        for (String name : names) {
                            int index = new Random().nextInt((int) size);
                            String commentId = (String)redisTemplate.opsForList().index(StringUtils.join(DOMAIN, TEMP_WEIGHT_KEY, commentType, ":", levelEnum), index);
                            Object commentObj = redisTemplate.opsForValue().get(StringUtils.join(DOMAIN, TEMP_DATA, commentId));
                            JSONObject commentJson = JSONObject.parseObject(JSONObject.toJSONString(commentObj));
                            CommentResultDto commentResultDto = new CommentResultDto();
                            commentResultDto.setType(commentType.getCode());
                            commentResultDto.setLevel(levelEnum.name());
                            commentResultDto.setContent(commentJson.getString("template"));
                            buildResultVo(autoCommentVos, name, commentResultDto);
                        }
                    }
                }
            }
        }
        for (AutoCommentVo autoCommentVo : autoCommentVos) {
            ConjunctionHandler.handle(autoCommentVo.getCommentResultList());
        }
        log.info("生成评语：" + autoCommentVos.size() + "条");
        return Response.success(autoCommentVos);
    }

    @Override
    public void initCommentData() {

        clearCommentData();

        QueryWrapper<CommentTemp> tempWrapper = new QueryWrapper<>();
        tempWrapper.eq("is_del", 0);
        List<CommentTemp> commentTempList = commentTempMapper.selectList(tempWrapper);
        Map<Integer, List<CommentTemp>> tempGroupBy = commentTempList.stream().collect(Collectors.groupingBy(CommentTemp::getTempType, Collectors.toList()));
        for (Map.Entry<Integer, List<CommentTemp>> entry : tempGroupBy.entrySet()) {
            for (CommentTemp commentTemp : entry.getValue()) {
                for (int i = 0; i < commentTemp.getWeight(); i++) {
                    redisTemplate.opsForList().leftPush(StringUtils.join(DOMAIN, TEMP_WEIGHT_KEY, CommentType.getEnumByCode(entry.getKey()), ":", commentTemp.getLevel()), commentTemp.getId());
                }
                redisTemplate.opsForValue().set(StringUtils.join(DOMAIN, TEMP_DATA, commentTemp.getId()), commentTemp);
            }
        }
    }

    @Override
    public void clearCommentData() {
        Set keys = redisTemplate.keys(StringUtils.join(DOMAIN, "*"));
        for (Object key : keys) {
            redisTemplate.delete(key);
        }
    }


    private void buildResultVo(List<AutoCommentVo> autoCommentVos, String name, CommentResultDto commentResultDto) {
        List<AutoCommentVo> match = autoCommentVos.stream().filter(v -> v.getStuName().equals(name)).collect(Collectors.toList());
        if (match == null || match.size() == 0) {
            AutoCommentVo autoCommentVo = new AutoCommentVo();
            autoCommentVo.setStuName(name);
            if (autoCommentVo.getCommentResultList() == null || autoCommentVo.getCommentResultList().size() == 0) {
                List<CommentResultDto> commentResultList = new ArrayList<>();
                commentResultList.add(commentResultDto);
                autoCommentVo.setCommentResultList(commentResultList);
            }
            autoCommentVos.add(autoCommentVo);
        } else {
            AutoCommentVo autoCommentVo = match.get(0);
            autoCommentVo.getCommentResultList().add(commentResultDto);
        }
    }
}
